package com.two.screen.water.balance.ui.service

import android.annotation.SuppressLint
import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.hardware.display.DisplayManager
import android.hardware.usb.UsbDevice
import android.os.*
import android.view.Display
import com.android.print.sdk.PrinterConstants
import com.android.print.sdk.PrinterInstance
import com.two.screen.water.balance.R
import com.two.screen.water.balance.bean.BaseBean
import com.two.screen.water.balance.bean.PropellingMessage
import com.two.screen.water.balance.bean.SoundData
import com.two.screen.water.balance.bean.database.ServerVipInfo
import com.two.screen.water.balance.bean.water.SocketResponseBean
import com.two.screen.water.balance.net.api.DataApi
import com.two.screen.water.balance.net.api.NormalApi
import com.two.screen.water.balance.net.observer.NormalObserver
import com.two.screen.water.balance.net.socket.IReceiveMessage
import com.two.screen.water.balance.net.socket.WebSocketManager
import com.two.screen.water.balance.print.PrinterAll
import com.two.screen.water.balance.print.android_print.bluetooth.BluetoothOperation
import com.two.screen.water.balance.print.android_print.bluetooth.BluetoothPrinter
import com.two.screen.water.balance.print.android_print.usb.AndroidUSBPrinter
import com.two.screen.water.balance.print.android_print.usb.UsbOperation
import com.two.screen.water.balance.serial.battery.BatteryAll
import com.two.screen.water.balance.serial.card.ReadCardAll
import com.two.screen.water.balance.serial.weight.WeightAll
import com.two.screen.water.balance.ui.activity.StartUseActivity
import com.two.screen.water.balance.ui.activity.presentation.ViceScreenDisplay
import com.two.screen.water.balance.utils.*
import com.two.screen.water.balance.utils.eventbus.Event
import com.two.screen.water.balance.utils.eventbus.EventBusUtil
import com.two.screen.water.balance.utils.eventbus.EventCode
import com.two.screen.water.balance.utils.eventbus.EventCode.Companion.READER_CARD_HEX_STRING
import com.two.screen.water.balance.utils.eventbus.EventCode.Companion.TOAST_MESSAGE
import com.two.screen.water.balance.utils.voice.VoicePlay
import com.two.screen.water.balance.utils.voice.constant.VoiceConstants
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * 离屏渲染服务
 */
class AppService : Service() {
    /**
     * 屏幕管理器
     */
    private var mDisplayManager: DisplayManager? = null

    /**
     * 屏幕数组
     */
    private var mDisplay: Array<Display>? = null

    /**
     * 第二块屏 副屏 称重
     */
    var viceScreenDisplay: ViceScreenDisplay? = null

    /**
     * 第二块屏 副屏 待机
     */
    //var viceScreenDisplay: ViceScreenAwaitDisplay? = null

    override fun onCreate() {
        DataApi.initData()//优先初始化数据
        super.onCreate()
        if (!EventBus.getDefault().isRegistered(this)) EventBusUtil.register(this)
        d("onCreate")
        startForeground()

        //BannerApi.initBannerApi()
        initPrintAndWeight()
        connectBySocket()
    }

    private fun connectBySocket() {
        WebSocketManager.instance.init(object : IReceiveMessage {
            override fun onConnectSuccess() {
            }

            override fun onConnectFailed() {
            }

            override fun onClose() {
            }

            override fun onMessage(text: String?) {
                d("connectBySocket->onMessage-text:$text")
                var socketResponseBean = try {
                    CommUtils.gson.fromJson(text, SocketResponseBean::class.java)
                } catch (e: Exception) {
                    d("connectBySocket->onMessage-error:$e")
                    null
                }
                if (socketResponseBean != null) {
                    when (socketResponseBean.type) {
                        "paySucceed" -> EventBusUtil.sendEvent(Event(EventCode.SOCKET_RESULT_PAY, socketResponseBean))
                        "authorization" -> allowReject(socketResponseBean)
                    }
                }
            }
        })
    }

    private fun allowReject(socketResponseBean: SocketResponseBean) {
        if ("close" == socketResponseBean.cmd) {
            //TODO:这里会导致收银操作收银丢失数据，
            ToastUtil.showToast("授权已拒接")
            DataApi.resetData()
            CommUtils.goBackFirstActivity(this)
        }
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        d("onStartCommand")
        return super.onStartCommand(intent, flags, startId)
    }


    private fun initPrintAndWeight() {
        d("initPrintAndWeight start")
        PrinterAll.printerInit()
        WeightAll.initSerialPortWeight()
        BatteryAll.initSerialPortBattery()
        ReadCardAll.initSerialPortBattery()
        //初始化读卡器
    }

    /**
     * 设置服务在前台可见
     */
    private fun startForeground() {
        /**
         * 创建Notification
         */
        val notificationChannel: NotificationChannel
        val notification: Notification
        var pendingIntent = PendingIntent.getActivity(this, 0, Intent(this, StartUseActivity::class.java), 0)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = NotificationChannel(
                applicationContext.packageName,
                this::class.java.name, NotificationManager.IMPORTANCE_HIGH
            )
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.RED
            notificationChannel.setShowBadge(true)
            notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(notificationChannel)
            notification = Notification.Builder(this, "123")
                .setContentTitle(getString(R.string.app_name))
                .setContentTitle(getString(R.string.app_name))
                .setChannelId(applicationContext.packageName)
                //.setSmallIcon(R.mipmap.logo)
                .setContentIntent(pendingIntent)
                .build()
        } else {
            notification = Notification.Builder(this)
                .setContentTitle(getString(R.string.app_name))
                .setContentTitle(getString(R.string.app_name))
                //.setSmallIcon(R.drawable.sym_call_incoming)
                .setContentIntent(pendingIntent)
                .build()
        }
        /**
         * 设置notification在前台展示
         */
        startForeground(1, notification)
    }

    override fun onBind(intent: Intent): IBinder? {
        return MultiScreenBinder()
    }

    inner class MultiScreenBinder : Binder() {
        val service: AppService
            get() = this@AppService
    }

    private fun showViceScreenDisplay() {
        //d("viceScreenDisplay:$viceScreenDisplay")
        try {
            viceScreenDisplay?.show()
        } catch (e: Exception) {
            ToastUtil.showToast("富屛启动失败：$e")
        }
    }

    override fun onDestroy() {
        try {
            d("onDestroy")
            WebSocketManager.instance.close()
            PrinterAll.printerClose()
            WeightAll.weightClose()
            BatteryAll.batteryClose()
            ReadCardAll.readCardClose()
            viceScreenDisplay?.dismiss()
            viceScreenDisplay = null
            EventBusUtil.unregister(this)
            BluetoothPrinter.closeBluetoothPrinter()
            stopForeground(true)
            super.onDestroy()
        } catch (e: Exception) {
            e.printStackTrace()
            d("服务关闭失败？$e")
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBusCome(event: Event<Any>?) {
        when (event?.code) {
            TOAST_MESSAGE -> ToastUtil.showToast(event.data as String)
            READER_CARD_HEX_STRING -> checkVipInfo(event.data as String)
            EventCode.BLUETOOTH_PRINT_CLOSE -> BluetoothPrinter.closeBluetoothPrinter()
            EventCode.BLUETOOTH_PRINT_REBIND -> {
                BluetoothPrinter.myOpertion = BluetoothOperation(this, mBluetoothHandler)
                BluetoothPrinter.myOpertion?.chooseDevice()
            }
            EventCode.ANDROID_USB_PRINT_OPEN -> openAndroidUSBPrinter(event)
            EventCode.JPUSH_MSG -> {
                var propellingMessage = event.data as PropellingMessage
                val moneyMsg = propellingMessage.msg
                d("JPushInterface.getAlias:moneyMsg:$moneyMsg,mIsOpenPayVoice:${DataApi.mIsOpenPayVoice}")
                if (!DataApi.mIsOpenPayVoice) return
                when {
                    moneyMsg?.contains("支付宝") == true -> playSound(SoundData(VoiceConstants.SUCCESS_ALI_PAY, moneyMsg))
                    moneyMsg?.contains("微信") == true -> playSound(SoundData(VoiceConstants.SUCCESS_WECHAT_PAY, moneyMsg))
                    else -> playSound(SoundData(VoiceConstants.SUCCESS_OTHER_PAY, moneyMsg))
                }
            }
        }
    }

    /*播放收款语音，不兼容安卓7，不知为啥*/
    fun playSound(soundData: SoundData) {
        if (soundData.money != null)
            VoicePlay.with(this).play(soundData.money, soundData.start)
        else
            VoicePlay.with(this).play(soundData.start, soundData.isContinuePlay)
    }


    private fun openAndroidUSBPrinter(event: Event<Any>) {
        try {
            AndroidUSBPrinter.myOpertion = UsbOperation(this, mUsbHandler)
            AndroidUSBPrinter.myOpertion?.mPrinter = PrinterInstance(this, event.data as UsbDevice, mUsbHandler)
            AndroidUSBPrinter.myOpertion?.mPrinter?.openConnection()
        } catch (e: Exception) {
            d("ANDROID_USB_PRINT_OPEN error:$e")
        }
    }

    private fun checkVipInfo(carNum: String) {
        if (isReturnCheckVipInfo()) return
        NormalApi.getVipInfo(
            sortedMapOf(Params.tp to 3, Params.card_n to carNum), Urls.memberCard
        )
            .compose(RxUtils.io())
            .subscribe(object : NormalObserver<ServerVipInfo>() {
                override fun onSuccessNext(t: BaseBean<out ServerVipInfo>) {
                    var data = t.data!!
                    val sb = StringBuilder()
                    sb.appendLine("名称：${data.name.isNotAvailable()}")
                    sb.appendLine("手机：${data.mobile.isNotAvailable()}")
                    sb.appendLine("卡号：${data.card_n.isNotAvailable()}")
                    sb.appendLine("积分：${data.integral.isNotAvailable()}")
                    sb.appendLine("余额：${data.money.isNotAvailable()}")
                    ToastUtil.showToast(sb.toString())
                }
            })
    }


    //用于接受蓝牙连接状态消息的 Handler
    @SuppressLint("HandlerLeak")
    private var mBluetoothHandler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            //这里的消息好像针对 wifi打印
            d("handleMessage-msg:${msg.what}")
            when (msg.what) {
                PrinterConstants.Connect.SUCCESS -> {
                    BluetoothPrinter.isConnected = true
                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_SUCCESS))
                    d("BluetoothPrinter->connect success")
                }
                PrinterConstants.Connect.FAILED -> {
                    BluetoothPrinter.isConnected = false
                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                    d("BluetoothPrinter->connect failed")
                }
                PrinterConstants.Connect.CLOSED -> {
                    BluetoothPrinter.isConnected = false
                    d("BluetoothPrinter->connect close")
                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                }
                PrinterConstants.Connect.NODEVICE -> {
                    BluetoothPrinter.isConnected = false
                    d("BluetoothPrinter->no devices")
                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                }
                else -> {}
            }
            BluetoothPrinter.isConnecting = false
        }
    }

    //用于接受AndroidUsbPrint连接状态消息的 Handler
    @SuppressLint("HandlerLeak")
    private var mUsbHandler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            //这里的消息好像针对 wifi打印
            d("handleMessage-msg:${msg.what}")
            when (msg.what) {
                PrinterConstants.Connect.SUCCESS -> {
                    AndroidUSBPrinter.mIsOpenSuccess = true
//                    BluetoothPrinter.isConnected = true
//                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_SUCCESS))
                    d("mUsbHandler->connect success")
                }
                PrinterConstants.Connect.FAILED -> {
                    AndroidUSBPrinter.mIsOpenSuccess = false
//                    BluetoothPrinter.isConnected = false
//                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                    d("mUsbHandler->connect failed")
                }
                PrinterConstants.Connect.CLOSED -> {
                    AndroidUSBPrinter.mIsOpenSuccess = false
//                    BluetoothPrinter.isConnected = false
//                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                    d("mUsbHandler->connect close")
                }
                PrinterConstants.Connect.NODEVICE -> {
                    AndroidUSBPrinter.mIsOpenSuccess = false
//                    BluetoothPrinter.isConnected = false
//                    EventBusUtil.sendEvent(Event(EventCode.BLUETOOTH_PRINT_OPEN_FAILED))
                    d("mUsbHandler->no devices")
                }
                else -> {}
            }
        }
    }


    companion object {
        private fun d(msg: String) {
            CommUtils.println("AppService->", msg)
        }

        var mCurrentRunActivity: String? = null


        fun startAppService(context: Context) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(Intent(context, AppService::class.java));
            } else {
                context.startService(Intent(context, AppService::class.java))
            }
        }
    }

    fun isReturnCheckVipInfo(): Boolean {
        val b =
            "com.two.screen.water.balance.ui.activity.CollectMoneyActivity" == mCurrentRunActivity ||
                    "com.two.screen.water.balance.ui.activity.SystemSettingActivity" == mCurrentRunActivity
        return b
    }
}